package design.onekey.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import design.onekey.base.BaseEntity;
import design.onekey.base.PageEntity;
import design.onekey.constant.StatusCode;
import design.onekey.model.dto.UserInfoDto;
import design.onekey.exception.BizException;
import design.onekey.mapper.SysOrgMapper;
import design.onekey.mapper.UserAccountOrgMapper;
import design.onekey.model.SysOrg;
import design.onekey.model.dto.BaseOrgTreeDto;
import design.onekey.model.dto.SysOrgWithAuthDto;
import design.onekey.model.dto.SysOrgWithPtDto;
import design.onekey.model.dto.UserAccountOrg;
import design.onekey.service.ISysOrgService;
import design.onekey.util.MessageUtil;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* @Description: SysOrg服务实现
* @author
* @date 2020-06-05 04:03:14
* @version V1.0
 */
@Service
public class SysOrgServiceImpl extends ServiceImpl<SysOrgMapper, SysOrg> implements ISysOrgService {

	@Autowired
	private UserAccountOrgMapper userAccountOrgMapper;


	/**
	* @Title: tablePagingQuery
	* @Description: 表格分页查询
	* @param @param model
	* @return BaseEntity
	* @author
	* @throws
	*/
	@Override
	public PageEntity tablePagingQuery(SysOrg model) {
		PageEntity result = new PageEntity();
		model.setDelFlag(1);
		com.github.pagehelper.Page<?> page = PageHelper.startPage(model.getCurrentPage(), model.getPageSize()); //分页条件
		QueryWrapper<SysOrg> queryWrapper = new QueryWrapper<>();
		if(model.getOrgName() != null) {
			queryWrapper.eq("org_name", model.getOrgName());
		}
		List<SysOrg> list = this.baseMapper.selectList(queryWrapper);
		result.setData(list);
		result.setTotal(page.getTotal());
		result.setCurrentPage(model.getCurrentPage());
		result.setPageSize(model.getPageSize());
		return result;
	}

	/**
	 * @Method getFirstLayer
	 * @Author zhangcheng
	 * @Version  1.0
	 * @Description 查询下一层子节点信息
	 * @Exception
	 * @Date 2020-6-8 11:36
	 */
	@Override
	public List<SysOrg> getNextLayer(Long id, UserInfoDto userInfoDto) {
		//判断是不是第一层
		if (id == 0){
			//判断是否是超级管理
			if (userInfoDto.getIsAdmin() == 1){
				return this.baseMapper.selectList(new QueryWrapper<SysOrg>().eq("parent_org_id",0).eq("del_flag", 1));
			}else{
				return this.baseMapper.selectList(new QueryWrapper<SysOrg>().in("id",userInfoDto.getOrgId()).eq("del_flag", 1));
			}
		}else{
			return this.baseMapper.selectList(new QueryWrapper<SysOrg>().eq("parent_org_id",id).eq("del_flag", 1));
		}
	}

	/**
	 * @Method getOrgTreeById
	 * @Author zhangcheng
	 * @Version  1.0
	 * @Description 根据父节点查询组织机构树
	 * @Exception
	 * @Date 2020-6-8 13:40
	 */
	@Override
	public BaseEntity getOrgTreeById(Long id) {
		BaseOrgTreeDto baseOrgTreeDto;
		/*判断是否为根节点*/
		if (id!=0){
			SysOrg sysOrg = (SysOrg) this.baseMapper.selectById(id);
			baseOrgTreeDto = BaseOrgTreeDto.builder().id(sysOrg.getId()).parentId(sysOrg.getParentOrgId()).name(sysOrg.getOrgName()).build();
		}else{
			baseOrgTreeDto = BaseOrgTreeDto.builder().id(0L).parentId(0L).name("root").build();
		}
		recursionFn(baseOrgTreeDto);
		return baseOrgTreeDto;
	}

	/**
	 * @Method tablePagingQueryByAuthority
	 * @Author zhangcheng
	 * @Version  1.0
	 * @Description 根据权限查询分页组织
	 * @Return com.baiyyy.yfz.base.BaseEntity
	 * @Exception
	 * @Date 2020-6-9 10:29
	 */
	@Override
	public BaseEntity tablePagingQueryByAuthority(SysOrg model, UserInfoDto userInfoDto) {
		Long orgId = userInfoDto.getOrgId();
		PageEntity result = new PageEntity();
		model.setDelFlag(1);
		Page page = PageHelper.startPage(model.getCurrentPage(), model.getPageSize()); //分页条件
		SysOrgWithAuthDto sysOrgWithAuth = new SysOrgWithAuthDto();
		sysOrgWithAuth.setSysOrg(model);
		//判断是不是超级管理员
		if (userInfoDto.getIsAdmin() == 1){
			sysOrgWithAuth.setOrgIds(null);
		}else{
			Set<Long> set = new HashSet<>();
			List<Long> orgIds = new ArrayList<Long>();
			orgIds.add(orgId);
			this.loadAllOrgByIds(orgIds,set);
			sysOrgWithAuth.setOrgIds(new ArrayList<>(set));
		}
		List<SysOrgWithPtDto> list = this.baseMapper.searchDataLikeByAuthority(sysOrgWithAuth);
		result.setData(list);
		result.setTotal(page.getTotal());
		result.setCurrentPage(model.getCurrentPage());
		result.setPageSize(model.getPageSize());
		return result;
	}

	/**
	 * @Method recursionFn
	 * @Author zhangcheng
	 * @Version  1.0
	 * @Description 递归查询赋值节点
	 * @Return void
	 * @Exception
	 * @Date 2020-6-8 14:02
	 */
	private void recursionFn(BaseOrgTreeDto defaultTree){
		if (hasChild(defaultTree)){
			List<SysOrg> parent_org_id = this.baseMapper.selectList(new QueryWrapper<SysOrg>().eq("parent_org_id", defaultTree.getId()));
			List<BaseOrgTreeDto> collect = parent_org_id.stream().map(p -> new BaseOrgTreeDto(p.getId(), p.getParentOrgId(), p.getOrgName())).collect(Collectors.toList());
			defaultTree.setChildList(collect);
			defaultTree.setOpen(true);
			for (BaseOrgTreeDto b:collect
				 ) {
				recursionFn(b);
			}
		}else {
			defaultTree.setOpen(false);
		}
	}

	/**
	 * @Method recursionFn
	 * @Author zhangcheng
	 * @Version  1.0
	 * @Description 递归组织机构的所有子组织
	 * @Return void
	 * @Exception
	 * @Date 2020-6-10 13:43
	 */
	private void recursionFn(Set<Long> rids,Long id){
		if (id!=0) {
			rids.add(id);
			if (hasChild(id)) {
				List<SysOrg> parent_org_id = this.baseMapper.selectList(new QueryWrapper<SysOrg>().eq("parent_org_id", id));
				List<Long> collect = parent_org_id.stream().map(p -> p.getId()).collect(Collectors.toList());
				for (Long c:collect
					 ) {
					recursionFn(rids,c);
				}
			}
		}
	}

	/**
	 * @Method hasChild
	 * @Author zhangcheng
	 * @Version  1.0
	 * @Description 根据结构树判断是否还有子节点
	 * @Return boolean
	 * @Exception
	 * @Date 2020-6-8 14:02
	 */
	private boolean hasChild(BaseOrgTreeDto baseOrgTreeDto){
		return this.baseMapper.selectCount(new QueryWrapper<SysOrg>().eq("parent_org_id", baseOrgTreeDto.getId())) != 0;
	}

	/**
	 * @Method hasChild
	 * @Author zhangcheng
	 * @Version  1.0
	 * @Description 根据id差点此节点是否有子节点
	 * @Return boolean
	 * @Exception
	 * @Date 2020-6-10 9:49
	 */
	private boolean hasChild(Long parentId){
		return this.baseMapper.selectCount(new QueryWrapper<SysOrg>().eq("parent_org_id", parentId)) != 0;
	}

	/**
	 * @Method loadAllOrgByIds
	 * @Author zhangcheng
	 * @Version  1.0
	 * @Description 查询组织机构列表下的全部组织机构
	 * @Return void
	 * @Exception
	 * @Date 2020-6-10 13:31
	 */
	public void loadAllOrgByIds(List<Long> ids, Set<Long> rids){
		for (Long id:ids
			 ) {
			recursionFn(rids,id);
		}
	}

	private boolean hasUser(Long orgId){
		Integer integer = userAccountOrgMapper.selectCount(new QueryWrapper<UserAccountOrg>().eq("org_id", orgId).eq("del_flag", 1));
		return integer != 0;
	}


	/**
	*<p>Title: getDetail</p>
	*<p>Description: 获取详情</p>
	* @author
	* @param id
	* @return
	*/
	@Override
	public BaseEntity getDetail(Long id) throws InvocationTargetException, IllegalAccessException {
		SysOrg byId = this.getById(id);
		SysOrgWithPtDto sysOrgWithPtDto = new SysOrgWithPtDto();
		BeanUtils.copyProperties(byId,sysOrgWithPtDto);
		if (byId.getParentOrgId() != 0){
			SysOrg pt = this.getById(byId.getParentOrgId());
			sysOrgWithPtDto.setPid(pt.getId());
			sysOrgWithPtDto.setPorgCode(pt.getOrgCode());
			sysOrgWithPtDto.setPorgName(pt.getOrgName());
			return sysOrgWithPtDto;
		}else{
			return sysOrgWithPtDto;
		}
	}

	/**
	*<p>Title: insert</p>
	*<p>Description: 新增数据并检查</p>
	* @author
	* @param model
	* @return
	*/
	@Transactional
	@Override
	public BaseEntity insert(SysOrg model,UserInfoDto userInfoDto) {
		QueryWrapper<SysOrg> queryWrapper = new QueryWrapper<SysOrg>().eq("org_code", model.getOrgCode()).eq("del_flag",1);
		Function<QueryWrapper<SysOrg>, Boolean> function = q->this.baseMapper.selectCount(q) != 0;
		if (this.checkRepeat(queryWrapper,function)){
			throw new BizException(StatusCode.CHECK_FAILURE, MessageUtil.getValue("error.check.exist",new String[]{"组织机构code码"}));
		}
		BaseEntity result = new BaseEntity();
		this.save(model);
		result.setStatusMsg(MessageUtil.getValue("info.insert"));
		return result;
	}

	/**
	*<p>Title: update</p>
	*<p>Description: 更新数据并检查</p>
	* @author
	* @param model
	* @return
	*/
	@Transactional
	@Override
	public BaseEntity update(SysOrg model,UserInfoDto userInfoDto) {
		QueryWrapper<SysOrg> queryWrapper = new QueryWrapper<SysOrg>().eq("org_code", model.getOrgCode()).ne("id",model.getId()).
				eq("del_flag",1);
		Function<QueryWrapper<SysOrg>, Boolean> function = q->this.baseMapper.selectCount(q) != 0;
		if (this.checkRepeat(queryWrapper,function)){
			throw new BizException(StatusCode.CHECK_FAILURE,MessageUtil.getValue("error.check.exist",new String[]{"组织机构code码"}));
		}
		BaseEntity result = new BaseEntity();
		this.updateById(model);
		result.setStatusMsg(MessageUtil.getValue("info.update"));
		return result;
	}

	/**
	*<p>Title: delete</p>
	*<p>Description: 单条删除数据</p>
	* @author
	* @param model
	* @return
	*/
	@Transactional
	@Override
	public BaseEntity delete(Long id) {
		//如果存在子节点组织或者组织下存在用户
		if (!hasChild(id)) {
			if (!hasUser(id)) {
				SysOrg sysOrg = new SysOrg();
				sysOrg.setId(id);
				sysOrg.setDelFlag(2);
				this.updateById(sysOrg);
				BaseEntity result = new BaseEntity();
				result.setStatusMsg(MessageUtil.getValue("info.delete"));
				return result;
			}else {
				throw new BizException(StatusCode.CHECK_FAILURE,MessageUtil.getValue("error.delete.exist",new String[]{"该组织机构下用户"}));
			}
		}else{
			throw new BizException(StatusCode.CHECK_FAILURE,MessageUtil.getValue("error.delete.exist",new String[]{"该组织机构下级组织机构"}));
		}
	}



	/**
	*<p>Title: deleteBatch</p>
	*<p>Description: 批量删除数据</p>
	* @author
	* @param list
	* @return
	*/
	@Transactional
	@Override
	public BaseEntity deleteBatch(List<Long> ids) {
		List<SysOrg> list = new ArrayList<SysOrg>();
		for (int i = 0; i < ids.size(); i++) {
			if (!hasChild(ids.get(i))) {
				if (!hasUser(ids.get(i))) {
					SysOrg sysOrg = new SysOrg();
					sysOrg.setId(ids.get(i));
					sysOrg.setDelFlag(2);
					list.add(sysOrg);
				}else {
					throw new BizException(StatusCode.CHECK_FAILURE,MessageUtil.getValue("error.delete.exist",new String[]{"该组织机构下用户"}));
				}
			}else{
				SysOrg detail = this.getById(ids.get(i));
				throw new BizException(StatusCode.CHECK_FAILURE,MessageUtil.getValue("error.delete.exist",new String[]{detail.getOrgName()+"组织机构的下级组织机构"}));
			}
		}
		BaseEntity result = new BaseEntity();
		if (list != null && list.size() > 0) {
			this.updateBatchById(list);
		}
		result.setStatusMsg(MessageUtil.getValue("info.delete"));
		return result;
	}


}
